<!DOCTYPE html>
<html>

<head>
  <title>Unit Tests</title>
  <link rel="stylesheet" href="https://code.jquery.com/qunit/qunit-2.16.0.css">
</head>

<body>
  <div id="qunit"></div>
  <div id="qunit-fixture"></div>

  <div id="helpButton" class="help-button">
    <span class="help-icon">?</span>
  </div>

  <div id="helpDialog" class="help-dialog">
    <h2>帮助</h2>
    <p>快捷键列表:</p>
    <ul>
      <li>cr - 复制行列</li>
      <li>CR - 删除行列</li>
      <li>wasd - 移动行列</li>
    </ul>
  </div>

  <div class="matrix-container">
    <p id="matrix-name">_</p>
    <p>=</p>
    <span id="left-bracket"></span>
    <table id="matrix-table">
      <!-- Matrix table content will be dynamically generated -->
    </table>
    <span id="right-bracket"></span>
  </div>

  <script src="https://code.jquery.com/qunit/qunit-2.16.0.js"></script>
  <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
  <script src="/static/ast.js"></script>
  <script src="/static/matrix.js"></script>
  <script src="/static/matrix-ui.js"></script>
  <script>
    function makeTableRow(inputValues) {
      let htmlString = '<tr>';
      inputValues.forEach(value => {
        htmlString += '<td><input type="text" value="' + value + '"></td>';
      });
      htmlString += '</tr>';
      return $(htmlString);
    }

    QUnit.module("test UI", {
      setup: function () {
        $('#matrix-name').text('_for_test_only_');
      }
    });

    QUnit.testDone(function (testResult) {
      // Clear the '#matrix-table' element
      $('#matrix-table').empty();

      // Log the test result
      console.log(testResult);
    });

    QUnit.test("copyAndInsertRow should insert a copied row below the selected row", function (assert) {
      // Arrange
      var matrixTable = $('#matrix-table');
      var selectedRow = 0;
      var originalRow = makeTableRow([1, 2]);
      matrixTable.append(originalRow);
      saveMatrix();

      // Act
      copyAndInsertRow(selectedRow);

      // Assert
      var copiedRow = matrixTable.find('tr').eq(selectedRow + 1);
      var copiedInputs = copiedRow.find('input');
      assert.equal(copiedInputs.length, 2, "The inserted row should contain the same number of inputs as the original row");
      assert.equal(copiedInputs.eq(0).val(), "1", "The first input value should be copied correctly");
      assert.equal(copiedInputs.eq(1).val(), "2", "The second input value should be copied correctly");
    });

    QUnit.test("copyAndInsertColumn should insert a copied column to the right of the selected column", function (assert) {
      // Arrange
      var matrixTable = $('#matrix-table');
      var selectedCol = 0;
      var originalColumn = makeTableRow([1, 2]);
      matrixTable.append(originalColumn);

      // Act
      copyAndInsertColumn(selectedCol);

      // Assert
      var copiedColumn = matrixTable.find('tr').find('td').eq(selectedCol + 1);
      var copiedInputs = copiedColumn.find('input');
      assert.equal(copiedInputs.length, 1, "The inserted column should contain the same number of inputs as the original column");
      assert.equal(copiedInputs.eq(0).val(), "1", "The first input value should be copied correctly");
    });

    QUnit.test("deleteRowOrColumn should delete the selected row", function (assert) {
      // Arrange
      var matrixTable = $('#matrix-table');
      var selectedRow = 0;
      var originalRow = makeTableRow([1, 2]);
      matrixTable.append(originalRow, makeTableRow([3, 4]));
      saveMatrix();

      // Act
      deleteRowOrColumn(selectedRow, 0, 82);

      // Assert
      var rowLeft = matrixTable.find('tr');
      assert.equal(rowLeft.length, 1, "The selected row should be deleted");
    });

    QUnit.test("deleteRowOrColumn should not delete the only row when rowCount is 1", function (assert) {
      // Arrange
      var matrixTable = $('#matrix-table');
      var selectedRow = 0;
      var originalRow = makeTableRow([1, 2]);
      matrixTable.append(originalRow);
      saveMatrix();

      // Act
      deleteRowOrColumn(selectedRow, 0, 82);

      // Assert
      var rowLeft = matrixTable.find('tr');
      assert.equal(rowLeft.length, 1, "The only row should not be deleted");
    });

    QUnit.test("deleteRowOrColumn should delete the selected column", function (assert) {
      // Arrange
      var matrixTable = $('#matrix-table');
      var selectedCol = 0;
      var originalColumn = makeTableRow([1, 2]);
      matrixTable.append(originalColumn, makeTableRow([3, 4]));
      saveMatrix();

      // Act
      deleteRowOrColumn(0, selectedCol, 67);

      // Assert
      var columnLeft = matrixTable.find('tr').find('td');
      assert.equal(columnLeft.length, 2, "The selected column should be deleted");
    });
    QUnit.test("deleteRowOrColumn should not delete the only column when colCount is 1", function (assert) {
      // Arrange
      var matrixTable = $('#matrix-table');
      var selectedCol = 0;
      var originalColumn = makeTableRow([1, 2]);
      matrixTable.append(originalColumn);
      saveMatrix();

      // Act
      deleteRowOrColumn(0, selectedCol, 67);

      // Assert
      var columnLeft = matrixTable.find('tr').find('td');
      assert.equal(columnLeft.length, 1, "The only column should not be deleted");
    });

    QUnit.test("swapRowOrColumn should swap the selected row with the previous row", function (assert) {
      // Arrange
      var matrixTable = $('#matrix-table');
      window.selectedRow = 1;
      var firstRow = makeTableRow([1, 2]);
      var secondRow = makeTableRow([3, 4]);
      matrixTable.append(firstRow);
      matrixTable.append(secondRow);
      saveMatrix();

      // Act
      swapRowOrColumn(87);

      // Assert
      var rows = matrixTable.find('tr');
      assert.equal(rows.eq(0).html(), secondRow.html(), "The selected row should be swapped with the previous row");
      assert.equal(rows.eq(1).html(), firstRow.html(), "The previous row should be swapped with the selected row");
    });

    QUnit.test("swapRowOrColumn should swap the selected column with the previous column", function (assert) {
      // Arrange
      var matrixTable = $('#matrix-table');
      window.selectedCol = 1;
      var firstRow = makeTableRow([1, 2]);
      var secondRow = makeTableRow([3, 4]);
      matrixTable.append(firstRow);
      matrixTable.append(secondRow);
      var td01 = firstRow.find('td').eq(1).html();
      var td11 = secondRow.find('td').eq(1).html();
      saveMatrix();

      // Act
      swapRowOrColumn(65);

      // Assert
      var columns = matrixTable.find('tr').find('td');
      assert.equal(columns.eq(0).html(), td01, "The selected column should be swapped with the previous column");
      assert.equal(columns.eq(2).html(), td11, "The previous column should be swapped with the selected column");
    });

    QUnit.test("swapRowOrColumn should swap the selected row with the previous row in a 3x3 matrix", function (assert) {
      // Arrange
      var matrixTable = $('#matrix-table');
      window.selectedRow = 1;
      var firstRow = makeTableRow([1, 2, 3]);
      var secondRow = makeTableRow([4, 5, 6]);
      var thirdRow = makeTableRow([7, 8, 9]);
      matrixTable.append(firstRow);
      matrixTable.append(secondRow);
      matrixTable.append(thirdRow);
      saveMatrix();

      // Act
      swapRowOrColumn(87);

      // Assert
      var rows = matrixTable.find('tr');
      assert.equal(rows.eq(0).html(), secondRow.html(), "The selected row should be swapped with the previous row");
      assert.equal(rows.eq(1).html(), firstRow.html(), "The previous row should be swapped with the selected row");
    });

    QUnit.test("swapRowOrColumn should swap the selected column with the previous column in a 3x3 matrix", function (assert) {
      // Arrange
      var matrixTable = $('#matrix-table');
      window.selectedCol = 1;
      var firstRow = makeTableRow([1, 2, 3]);
      var secondRow = makeTableRow([4, 5, 6]);
      var thirdRow = makeTableRow([7, 8, 9]);
      matrixTable.append(firstRow);
      matrixTable.append(secondRow);
      matrixTable.append(thirdRow);
      var td01 = firstRow.find('td').eq(1).html();
      var td11 = secondRow.find('td').eq(1).html();
      var td21 = thirdRow.find('td').eq(1).html();
      saveMatrix();

      // Act
      swapRowOrColumn(65);

      // Assert
      var columns = matrixTable.find('tr').find('td');
      assert.equal(columns.eq(0).html(), td01, "The selected column should be swapped with the previous column");
      assert.equal(columns.eq(3).html(), td11, "The previous column should be swapped with the selected column");
      assert.equal(columns.eq(6).html(), td21, "The other columns should remain unchanged");
    });
  </script>
</body>

</html>